Adam
使用 Adam 算法更新参数权重。支持 Nesterov 动量。
算法逻辑如下:
\[\begin{split}m_t = m_{t-1} + (g_t - m_{t-1}) \cdot (1 - \beta_1) \\ v_t = v_{t-1} + (g_t^2 - v_{t-1}) \cdot (1 - \beta_2) \\ \hat{lr} = lr \cdot \frac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t}\end{split}\]如果不启用 Nesterov:
\[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t}{\sqrt{v_t} + \epsilon}\]如果启用 Nesterov:
\[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t \cdot \beta_1 + (1 - \beta_1) \cdot g_t}{\sqrt{v_t} + \epsilon}\]
- 输入:
m - 一阶矩向量地址(输入/输出)。
v - 二阶矩向量地址(输入/输出)。
gradient - 梯度向量地址。
weight - 权重向量地址(输入/输出)。
params - 一其他参数打包。
AdamParam定义如下
1 typedef struct {
2 float beta1; //阶矩估计的指数衰减率。
3 float beta2; //二阶矩估计的指数衰减率
4 float beta1_power; //:math:`\beta_1^t` 的值(指针形式传入)
5 float beta2_power; //:math:`\beta_2^t` 的值(指针形式传入)
6 float eps; // 数值稳定性项 epsilon
7 float learning_rate; // 学习率
8 int nesterov; // 是否启用 Nesterov 动量(0: 不启用, 1: 启用)
9 int start; // 计算的起始索引(包含)
10 int end; // 计算的结束索引(不包含)
11} AdamParam;
- 输出:
m - 更新后的一阶矩。
v - 更新后的二阶矩。
weight - 更新后的权重。
- 支持平台:
FT78NEMT7004
备注
支持fp32,fp16类型。
共享存储版本:
-
void fp_adam_s(float *m, float *v, const float *gradient, float *weight, AdamParam *params, int core_mask)
C调用示例:
1#include <stdio.h> 2 3int main(int argc, char* argv[]) { 4 // 假设所有数据均位于DDR空间 5 float* m = (float*)0xC0000000; 6 float* v = (float*)0xC1000000; 7 float* gradient = (float*)0xC2000000; 8 float* weight = (float*)0xC3000000; 9 10 // 标量参数 11 float beta1 = 0.9f; 12 float beta2 = 0.999f; 13 float beta1_power_val = 0.9f; // beta1^1 14 float beta2_power_val = 0.999f; // beta2^1 15 float* beta1_power = &beta1_power_val; 16 float* beta2_power = &beta2_power_val; 17 float eps = 1e-8f; 18 float learning_rate = 0.001f; 19 int nesterov = 1; 20 21 int start = 0; 22 int end = 800000; // 元素总数 23 int core_mask = 0xff; // 使用所有核心 24 25 AdamParam params = { 26 .beta1 = beta1, 27 .beta2 = beta2, 28 .beta1_power = beta1_power_val, 29 .beta2_power = beta2_power_val, 30 .eps = eps, 31 .learning_rate = learning_rate, 32 .nesterov = nesterov, 33 .start = 0, 34 .end = 800000 35 }; 36 37 fp_adam_s(m, v, gradient, weight, ¶ms, core_mask); 38 39 return 0; 40}
私有存储版本:
-
void fp_adam_p(float *m, float *v, const float *gradient, float *weight, AdamParam *params)
C调用示例:
1#include <stdio.h> 2 3int main(int argc, char* argv[]) { 4 // 假设所有数据均位于L2/AM空间 5 float* m = (float*)0x10820000; 6 float* v = (float*)0x10830000; 7 float* gradient = (float*)0x10840000; 8 float* weight = (float*)0x10850000; 9 10 float beta1 = 0.9f; 11 float beta2 = 0.999f; 12 float beta1_power_val = 0.9f; 13 float beta2_power_val = 0.999f; 14 float eps = 1e-8f; 15 float learning_rate = 0.001f; 16 int nesterov = 0; 17 int start = 0; 18 int end = 2000; 19 20 AdamParam params = { 21 .beta1 = beta1, 22 .beta2 = beta2, 23 .beta1_power = beta1_power_val, 24 .beta2_power = beta2_power_val, 25 .eps = eps, 26 .learning_rate = learning_rate, 27 .nesterov = nesterov, 28 .start = start, 29 .end = end 30 }; 31 32 fp_adam_p(m, v, gradient, weight, ¶ms); 33 34 return 0; 35}